using System;
using System.IO;
using System.Text;

namespace Org.EasyWeb.Upload
{
	internal sealed class MimePushReader
	{
		private enum MimeReaderState
		{
			ReadingHeaders,
			ReadingBody,
			CheckingEnd,
			Finished
		}

		private byte[] fBoundary;
		private Encoding fEncoding;
		private IMimePushHandler fHandler;
		private Stream fStream;

		public MimePushReader(Stream s, byte[] b, IMimePushHandler h, Encoding e)
		{
			fStream = s;
			fHandler = h;
			fBoundary = b;
			fEncoding = e;
		}

		private int ArrayIndexOf(byte[] array, byte test, int start, int end)
		{
			if (end < array.Length)
			{
				for (int i = start; i < end; i++)
				{
					if (array[i] == test)
					{
						return i;
					}
				}
			}
			else
			{
				for (int i = start; i < array.Length; i++)
				{
					if (array[i] == test)
					{
						return i;
					}
				}
			}
			return -1;
		}

		private int IndexOf(byte[] buffer, byte[] pattern, int start, int end)
		{
			int num1 = 0;
			int num2 = ArrayIndexOf(buffer, pattern[0], start, end);
			if (num2 != -1)
			{
				while ((num2 + num1) < end)
				{
					if (buffer[num2 + num1] == pattern[num1])
					{
						num1++;
						if (num1 == pattern.Length)
						{
							return num2;
						}
					}
					else
					{
						num2 = ArrayIndexOf(buffer, pattern[0], num2 + num1, end);
						if (num2 == -1)
						{
							return num2;
						}
						num1 = 0;
					}
				}
			}
			return num2;
		}

		public UploadState Parse(string fileTypeRule)
		{
			MimePushReader.MimeReaderState state = MimePushReader.MimeReaderState.ReadingHeaders;
			MimeHeaderReader reader = new MimeHeaderReader(fEncoding);
			byte[] buffer = new byte[0x2000];
			int num1 = fStream.Read(buffer, 0, buffer.Length);
			int num2 = IndexOf(buffer, fBoundary, 0, num1) + fBoundary.Length;
			if (buffer[num2] == 13)
			{
				num2 += 2;
			}
			else if (buffer[num2] == 10)
			{
				num2++;
			}
			while (state != MimePushReader.MimeReaderState.Finished)
			{
				int num3;
				switch (state)
				{
					case MimePushReader.MimeReaderState.ReadingHeaders:
						num2 += reader.Read(buffer, num2);
						if (reader.HeaderComplete)
						{
							state = MimePushReader.MimeReaderState.ReadingBody;
							UploadState uploadState = fHandler.BeginPart(reader.Headers, fileTypeRule);
							if (uploadState == UploadState.ReceivingData)
								reader.Reset();
							else
								return uploadState;
						}
						break;
					case MimePushReader.MimeReaderState.ReadingBody:
						#region ReadingBody
						num3 = IndexOf(buffer, fBoundary, num2, num1);
						if (num3 != -1)
						{
							int num4 = num3 - num2;
							if (num4 >= 2)
							{
								if (buffer[num3 - 2] == 13)
								{
									num4 -= 2;
								}
								else if (buffer[num3 - 2] == 10)
								{
									num4--;
								}
							}
							fHandler.PartData(ref buffer, num2, num4);
							if (num3 < (num1 - fBoundary.Length))
							{
								#region if
								if (num3 < (num1 - (fBoundary.Length + 2)))
								{
									bool flag1 = fEncoding.GetString(buffer, num3 + fBoundary.Length, 2) == "--";
									if (flag1)
										state = MimePushReader.MimeReaderState.Finished;
									else
										state = MimePushReader.MimeReaderState.ReadingHeaders;
									fHandler.EndPart(flag1);
									num2 += ((num3 + fBoundary.Length) - num2) + 2;
								}
								else
								{
									state = MimePushReader.MimeReaderState.CheckingEnd;
									if (((num3 + 2) - num1) == 1)
									{
										num3 = 1;
										buffer[0] = buffer[num1 - 1];
									}
									else
										num3 = 0;
									num1 = fStream.Read(buffer, num3, buffer.Length - num3);
									num2 = 0;
									num1 += num3;
								}
								#endregion
							}
							else
							{
								num3 -= (num3 - num2) - num4;
								int num5 = num1 - num3;
								Buffer.BlockCopy(buffer, num3, buffer, 0, num5);
								num1 = fStream.Read(buffer, num5, buffer.Length - num5);
								num2 = 0;
								num1 += num5;
							}
						}
						else
						{
							fHandler.PartData(ref buffer, num2, num1 - num2);
							num2 += num1 - num2;
						}
						#endregion
						break;
					case MimePushReader.MimeReaderState.CheckingEnd:
						if (fEncoding.GetString(buffer, 0, 2) != "--")
						{
							num2 += 2;
							state = MimePushReader.MimeReaderState.ReadingHeaders;
						}
						else
							state = MimePushReader.MimeReaderState.Finished;
						fHandler.EndPart(state == MimePushReader.MimeReaderState.Finished);
						break;
				}
				ReadStream(state, ref num1, ref num2, buffer);
			}

			return UploadState.ReceivingData;
		}

		private void ReadStream(MimeReaderState state, ref int num1, ref int num2, byte[] buffer)
		{
			if ((state != MimePushReader.MimeReaderState.Finished) && (num2 >= num1))
			{
				num1 = fStream.Read(buffer, 0, buffer.Length);
				num2 = 0;
			}
		}
	}
}
